package com.xb.service;

import com.xb.dao.DeptDao;
import com.xb.dao.MeetingDao;
import com.xb.entity.*;
import com.xb.mapper.MeetingMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class MeetingService {

    @Autowired
    MeetingDao meetingDao;

    @Autowired
    MeetingMapper meetingMapper;

    @Autowired
    DeptDao deptDao;


    private Specification<Meeting> createSpec(Map searchMap){
        return new Specification<Meeting>() {
            @Override
            public Predicate toPredicate(Root<Meeting> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                ArrayList<Predicate> predicateArrayList = new ArrayList<>();
                if (!StringUtils.isEmpty(searchMap.get("title"))) {
                    // 标题模糊查找
                    predicateArrayList.add(criteriaBuilder.like(root.get("title").as(String.class),
                            "%" + searchMap.get("title").toString() + "%"));
                }
                if (!StringUtils.isEmpty(searchMap.get("statue"))) {
                    // 状态精确查找
                    predicateArrayList.add(criteriaBuilder.equal(root.get("status").as(Long.class),
                            Long.parseLong(searchMap.get("status").toString())));
                }
                Predicate[] predicates = new Predicate[predicateArrayList.size()];

                return criteriaBuilder.and(predicateArrayList.toArray(predicates));
            }
        };
    }

    /**
     * 查询会议列表
     * @param searchMap 查询条件映射
     * @param page 当前页
     * @return 会议信息页面
     */
    public Page<Meeting> findMeeting(Map searchMap, Integer page) {
        Specification<Meeting> specification = createSpec(searchMap);
        return meetingDao.findAll(specification, PageRequest.of(page - 1,
                PageResult.PAGE_SIZE, Sort.by("publishDate").descending()));
    }

    /**
     * 添加会议
     * @param meeting 会议信息
     */
    public void save(Meeting meeting) {
        Long deptId = meeting.getDeptId();
        Dept dept = deptDao.findById(deptId).get();
        meeting.setDeptName(dept.getName());
        meeting.setPublishDate(new Date());
        meeting.setStatus(0L);
        meetingDao.save(meeting);
    }

    /**
     * 通过ID查询
     * @param id 会议ID
     * @return 会议信息
     */
    public Meeting findById(Long id) {
        return meetingDao.findById(id).get();
    }

    /**
     * 查询参加了会议的人
     * @param id 会议ID
     * @return 实到人数
     */
    public Integer countMeetingJoinByMeetingId(Long id) {
        return meetingMapper.countMeetingJoinByMeetingId(id);
    }

    /**
     * 查询用户是否需要参加会议
     * @param mId 会议ID
     * @param uId 用户ID
     * @return
     */
    public Boolean loginUserIsJoinMeeting(Long mId, Long uId) {
        return meetingMapper.countMeetingJoinByMeetingIdAndUserId(mId, uId) > 0;
    }

    /**
     * 用户参加会议
     * @param mId 会议ID
     * @param state 参加状态
     * @return
     */
    public String joinMeeting(Long uId, Long mId, Boolean state) {
        String msg;
        // 校验用户是否需要参加会议
        if (meetingMapper.countMeetingJoinByMeetingIdAndUserId(mId, uId) > 0) {
            if (state) {
                meetingDao.insertMeetingJoin(uId, mId);
                msg = "已参加会议";
            } else {
                meetingDao.deleteMeetingJoin(uId, mId);
                msg = "已退出会议";
            }
        } else msg = "非会议参加人员";
        return msg;
    }

    /**
     * 查询状态不为 status 的会议
     * @param status
     * @return
     */
    public List<Meeting> findByStatusNot(long status) {
        return meetingDao.findByStatusNot(status);
    }

    /**
     * 根据会议ID修改会议状态
     * @param mId 会议ID
     * @param status 会议状态
     */
    public void updateMeetingStatus(Long mId, long status) {
        meetingDao.updateMeetingStatus(mId, status);
    }
}
